#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>
#ifdef WIN32
#include <GL/glew.h>
#include <GL/glut.h>
#else
#include <GL/glew.h>
#include <GL/glut.h>
#endif
#include "draw.h"
#include "shader.h"
#include "utility.h"


#define	row 13
#define	col 9



TextureMemory tm(row, col);
Shader shader; 
Face * pFace ;


void prepare_data (Face * & face )
{
	Point point[3];
	point[0].x = -1.0; point[0].y = -1.0; point[0].z = 0.0 ; 
	point[1].x = 1.0; point[1].y = -1.0; point[1].z = 0.0 ;
	point[2].x = 0.0; point[2].y = 1.0; point[2].z = 0.0 ; 
	
	face = new Face (tm, 0, point);
}
void prepare_texture( Face  * & face)
{
	/*
	int i, j;
    
	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			//SRGBA color (1.0, c, c, 255);
			if (i %2 != j%2)
			{
				FRGBA color (1.0f, 1.0f,1.0f,1.0f);			
				tm.write(i, j, color );
			}
			else{
				//FRGBA color ( 0.75f, 0.0f,0.0f,1.0f);			
				FRGBA color ( 4.0f*float((i* col) + j ) / 255.0f, 0.0f,0.0f,1.0f);			
				tm.write(i, j, color );
			
	}
	*/
	// write texCoord 

	face->write_tex_param(100, 0);


}
void draw_triangles (Face * & face)
{		

	glBegin(GL_TRIANGLES);

	//face->draw(100,0);
	
	
        //glTexCoord2f(0.0, 0.0); glVertex3f(2.0 - 4.0 /* * col / row */ , -2.0, 0.0);//
        //glTexCoord2f(0.0, 1.0); glVertex3f(2.0, -2.0, 0.0);
        //glTexCoord2f(1.0, 1.0); glVertex3f(2.0, 2.0, 0.0);
        
	/*
	glTexCoord2f(texcoord.w, texcoord.h); glVertex3f(point[0].x, point[0].y, point[0].z);
	glTexCoord2f(texcoord.w + c, texcoord.h ); glVertex3f(point[1].x, point[1].y, point[1].z);
	glTexCoord2f(texcoord.w + k, texcoord.h + h); glVertex3f(point[2].x, point[2].y, point[2].z);
	*/
	glEnd();

	glFlush();
}

void init(void)
{    
	glClearColor (0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_FLAT);
	glEnable(GL_DEPTH_TEST);

	prepare_data(pFace);
	prepare_texture(pFace);
//	glPixelStoref(GL_UNPACK_ALIGNMENT, 2);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	
	//glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA_FLOAT32_ATI, 2048, 2048, 0, GL_RGBA, GL_FLOAT, NULL);


	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, row, col, 
				 0, GL_RGBA, GL_FLOAT, tm.getMemory());

}



void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glEnable(GL_TEXTURE_2D);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

	shader.set_uniform("h_off", tm.getHeightOffset());
	shader.set_uniform("w_off", tm.getWidthOffset());

	draw_triangles(pFace);


	glFlush();
	glDisable(GL_TEXTURE_2D);

}

void reshape(int w, int h)
{
	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0.0, 0.0, -3.6);
}

void keyboard (unsigned char key, int x, int y)
{
	switch (key) {
	case 27:
		exit(0);
		break;
	default:
		break;
	}
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(800, 450);
	glutInitWindowPosition(100, 100);
	glutCreateWindow(argv[0]);
	init();
	int major;
	int minor;
	getGLVersion(& major, & minor);
	std::cout<<major<<' '<<minor<<std::endl;

	getGLSLVerstion(&major, & minor);
	std::cout<<major<<' '<<minor<<std::endl;

	glewInit();
	if (glewIsSupported("GL_VERSION_2_0"))
		printf("Ready for OpenGL 2.0\n");
	else {
		printf("OpenGL 2.0 not supported\n");
		exit(1);
	}

#ifdef WIN32
	shader.load("D:\\workspace\\shader\\glsl\\minimal.vert", "D:\\workspace\\shader\\glsl\\mcolor.frag");
#else
	shader.load("../glsl/texture.vert", "../glsl/texture.frag");
#endif
	shader.bind();

	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutKeyboardFunc(keyboard);



	glutMainLoop();
	return 0; 
}
